package com.example.demo.service.My.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.common.ErrorCode;
import com.example.demo.constant.CommonConstant;
import com.example.demo.exception.BusinessException;
import com.example.demo.mapper.MyUserMapper;
import com.example.demo.myModel.entity.Teacher;
import com.example.demo.myModel.otd.user.AdminLoginRequest;
import com.example.demo.myModel.otd.user.UserLoginRequest;
import com.example.demo.myModel.entity.Email;
import com.example.demo.myModel.entity.MyUser;
import com.example.demo.myModel.otd.user.UserQueryRequest;
import com.example.demo.myModel.vo.AdminLoginVo;
import com.example.demo.myModel.vo.UserLoginVo;
import com.example.demo.service.My.MyUserService;
import com.example.demo.utils.SqlUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Random;

import static com.example.demo.constant.UserConstant.USER_LOGIN_STATE;


@Component

public class MyUserServiceImpl extends ServiceImpl<MyUserMapper, MyUser> implements MyUserService {

    /**
     * 盐值，混淆密码
     */
    private static final String SALT = "example.demo";


    @Autowired
    private JavaMailSenderImpl mailSender;

    // application.properties配置的值
    @Value("${spring.mail.username}")
    private String from;

    /**
     * 注册
     *
     * @param myUser 注册信息类
     * @return {
     * 1111252522
     * }
     */
    @Override
    public long userRegister(MyUser myUser, HttpSession session) {
        // 1. 校验
        if (StringUtils.isAnyBlank(myUser.getUserId().toString(), myUser.getPassword(), myUser.getUserName())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        if (myUser.getPassword().length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短");
        }
        if (myUser.getUserId().toString().length() < 4) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短");
        }
        if (!registered(myUser, session)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码错误，请重新输入");
        }
        synchronized (myUser.getUserId().toString().intern()) {
            // 账户不能重复
            QueryWrapper<MyUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("userId", myUser.getUserId());
            long count = this.baseMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
            }
            // 2. 加密
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + myUser.getPassword()).getBytes());
            // 3. 插入数据
            MyUser user = new MyUser();
            user = myUser;
            user.setPassword(encryptPassword);
            user.setID(Long.parseLong(randomCode(8)));
            boolean saveResult = this.save(user);
            if (!saveResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败，数据库错误");
            }
            return user.getID();
        }
    }


    /**
     * 学生登录
     *
     * @param userLoginRequest 登录信息
     * @param request          网络请求信息
     * @return {
     * LoginUserVO
     * }
     */
    @Override
    public UserLoginVo userLogin(UserLoginRequest userLoginRequest, HttpServletRequest request) {
        // 1. 校验
        if (userLoginRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        if (userLoginRequest.getUserId().toString().length() < 4) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误");
        }
        if (userLoginRequest.getPassword().length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");
        }
        // 2. 加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userLoginRequest.getPassword()).getBytes());
        // 查询用户是否存在
        QueryWrapper<MyUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userLoginRequest.getUserId());
        queryWrapper.eq("password", encryptPassword);
        queryWrapper.eq("roleId",userLoginRequest.getRoleId());
        System.out.println(queryWrapper.getSqlSelect());
        MyUser user = this.baseMapper.selectOne(queryWrapper);
        // 用户不存在
        if (user == null) {
            //log.info("user login failed, userAccount cannot match userPassword");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");
        }
        // 3. 记录用户的登录态
        request.getSession().setAttribute(USER_LOGIN_STATE, user);
        return this.getLoginUserVO(user);
    }


    /**
     * 获取当前登录用户信息
     *
     * @param request 请求信息
     * @return {
     * MyUser
     * }
     */
    @Override
    public MyUser getLoginUser(HttpServletRequest request) {
        // 先判断是否已登录
        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        MyUser currentUser=null;
       try {
            currentUser = (MyUser) userObj;
           if (currentUser == null || currentUser.getUserId() == null) {
               throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
           }
           // 从数据库查询
           long userId = currentUser.getID();
           currentUser = this.getById(userId);
           if (currentUser == null) {
               throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
           }

       }
       catch ( Exception e){

       }
        return currentUser;
    }

    @Override
    public MyUser getLoginUserPermitNull(HttpServletRequest request) {
        return null;
    }

    @Override
    public boolean isAdmin(HttpServletRequest request) {
        return false;
    }

    @Override
    public boolean isAdmin(MyUser myUser) {
        return false;
    }

    @Override
    public boolean userLogout(HttpServletRequest request) {
        return false;
    }

    @Override
    public UserLoginVo getLoginUserVO(MyUser myUser) {
        if (myUser == null) {
            return null;
        }
        UserLoginVo loginUserVO = new UserLoginVo();
        BeanUtils.copyProperties(myUser, loginUserVO);
        return loginUserVO;
    }


    /**
     * 获取已经登录的管理员脱敏信息
     *
     * @param teacher 管理员信息
     * @return {AdminLoginVo}
     */
    @Override
    public AdminLoginVo getLoginAdminVO(Teacher teacher) {
        if (teacher == null) {
            return null;
        }
        AdminLoginVo loginAdminVO = new AdminLoginVo();
        BeanUtils.copyProperties(teacher, loginAdminVO);
        return loginAdminVO;
    }

    @Override
    public UserLoginVo getUserVO(MyUser myUser) {
        return null;
    }

    @Override
    public List<UserLoginVo> getUserVO(List<MyUser> myUserList) {
        return null;
    }

    @Override
    public QueryWrapper<MyUser> getQueryWrapper(UserQueryRequest userQueryRequest) {
        if (userQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        Long id = userQueryRequest.getId();
        String userAccount = userQueryRequest.getUserAccount();
        String unionId = userQueryRequest.getUnionId();
        String mpOpenId = userQueryRequest.getMpOpenId();
        String userName = userQueryRequest.getUserName();
        String userProfile = userQueryRequest.getUserProfile();
        String userRole = userQueryRequest.getUserRole();
        String sortField = userQueryRequest.getSortField();
        String sortOrder = userQueryRequest.getSortOrder();
        QueryWrapper<MyUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(id != null, "id", id);
        queryWrapper.eq(StringUtils.isNotBlank(unionId), "unionId", unionId);
        queryWrapper.eq(StringUtils.isNotBlank(userAccount), "userAccount", userAccount);
        queryWrapper.eq(StringUtils.isNotBlank(mpOpenId), "mpOpenId", mpOpenId);
        queryWrapper.eq(StringUtils.isNotBlank(userRole), "userRole", userRole);
        queryWrapper.like(StringUtils.isNotBlank(userProfile), "userProfile", userProfile);
        queryWrapper.like(StringUtils.isNotBlank(userName), "userName", userName);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }


    /**
     * 发送邮箱验证码
     *
     * @param email
     * @param session
     * @return
     */
    @Override
    public boolean sentEmailCode(Email email, HttpSession session) {
        try {
            SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
            // 生成随机数
            String code = randomCode(6);

            // 将随机数放置到session中
            session.setAttribute("email", email.getEmail());
            session.setAttribute("code", code);
            session.setAttribute("userId", email.getUserId());
            System.out.println(session.getAttribute("code"));
            simpleMailMessage.setSubject("验证码邮件"); // 主题
            simpleMailMessage.setText("您收到的验证码是：" + code); // 内容
            simpleMailMessage.setFrom(from); // 发件人
            simpleMailMessage.setTo(email.getEmail()); // 收件人
            mailSender.send(simpleMailMessage); // 发送
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.toString());
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "发送失败");
        }
    }

    /**
     * 随机生成6位数的验证码
     *
     * @return String code
     */
    @Override
    public String randomCode(int n) {
        StringBuilder str = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < n; i++) {
            str.append(random.nextInt(10));
        }
        return str.toString();
    }


    /**
     * 检验验证码
     *
     * @param info
     * @param session
     * @return
     */
    @Override
    public boolean registered(MyUser info, HttpSession session) {
        // 获取session中的验证信息
        String email = (String) session.getAttribute("email");
        String code = (String) session.getAttribute("code");
        long userId = (long) session.getAttribute("userId");
        // 获取表单中的提交的验证信息
        String voCode = info.getCode();
        //如果emial数据为空或者不一致都失败
        if (email == null || email.isEmpty()) {
            //return "error,请重新注册";
            return false;
        } else if (!code.equals(voCode) || userId != info.getUserId()) {
            //return "error,请重新注册";
            return false;
        }
        // 跳转成功页面
        return true;
    }
}
